package com.codecrane.core.mybatis;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;


/**
 * Created by 752322896 on 2019/4/6.
 */
@Component
@Aspect
@Slf4j(topic = "THIRDPARTY_LOGGER")
@Order(Ordered.LOWEST_PRECEDENCE-1)
public class DataSourceAsp {
    @Pointcut("@annotation(com.codecrane.core.mybatis.UseDataSource)")
    public void useDataSource() {
    }
    @Around("useDataSource() && @annotation(anno)")
    public Object dataSourceSwitcher(ProceedingJoinPoint joinPoint, UseDataSource anno) throws Throwable {
        String ds="";
        if(anno.useHashKey()){
            ds=DataSourceType.getByKey(getHashKeyFromMethod(joinPoint));
        }else{
            DataSourceType value = anno.value();
            ds=value.getSource();
        }
        DataSourceSwitcher.setDataSourceKey(ds);
        try {
            Object result = joinPoint.proceed();
            return result;
        }catch (Exception e){
            throw e;
        }finally {
            DataSourceSwitcher.setDataSourceKey(DataSourceType.MYSQL.getSource());
        }
    }


    /**
     * @param joinPoint
     * @return
     */
    public String getHashKeyFromMethod(ProceedingJoinPoint joinPoint){
        MethodSignature signature=MethodSignature.class.cast(joinPoint.getSignature());
        Method method = signature.getMethod();
        Object[] args = joinPoint.getArgs();
        Parameter[] declaredFields = method.getParameters();
        int index=0;
        for(Parameter temp:declaredFields){
            Annotation[] annotations = temp.getAnnotations();
            for(Annotation anTemp:annotations){
                if(anTemp instanceof DSKey){
                    return String.valueOf(args[index]);
                }
            }
            index++;
        }
        return null;

    }

}
